package dk.mirasola.systemtraining.user.client.util;

import com.google.gwt.core.client.GWT;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import dk.mirasola.systemtraining.bridgewidgets.client.ui.RenderUtil;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.Suit;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.DistributionFilterGroup;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.DistributionFilterGroupItem;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.FitDistributionFilter;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.GroupItem;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.HcpSeatDistributionFilter;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.HcpSuitDistributionFilter;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.LogicOperatorGroupItem;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.MajorMinorDistributionFilter;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.NTDistributionFilter;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.ShapeDistributionFilter;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.distributionfiltertree.ShapeTypeDistributionFilter;
import dk.mirasola.systemtraining.user.client.i18n.DistributionFilterGroupRenderTexts;

public class DistributionFilterGroupRender {
    private static DistributionFilterGroupRenderTexts texts = GWT.create(DistributionFilterGroupRenderTexts.class);

    public static SafeHtml renderDistributionFilterGroup(DistributionFilterGroup distributionFilterGroup) {
        SafeHtmlBuilder sb = new SafeHtmlBuilder();
        renderDistributionFilterGroup(distributionFilterGroup, sb, true);
        return sb.toSafeHtml();
    }

    public static void renderDistributionFilterGroup(DistributionFilterGroup distributionFilterGroup, SafeHtmlBuilder sb) {
        renderDistributionFilterGroup(distributionFilterGroup, sb, true);
    }

    private static void renderDistributionFilterGroup(DistributionFilterGroup distributionFilterGroup, SafeHtmlBuilder sb, boolean top) {
        if (top && distributionFilterGroup.getInverted()) {
            sb.append(texts.inverted());
            sb.append(texts.groupStart());
        } else if (!top) {
            if (distributionFilterGroup.getInverted()) {
                sb.append(texts.inverted());
            }
            sb.append(texts.groupStart());
        }

        for (int i = 0; i < distributionFilterGroup.getGroupItems().size(); i++) {
            GroupItem groupItem = distributionFilterGroup.getGroupItems().get(i);
            renderGroupItem(groupItem, sb);
            if (i < distributionFilterGroup.getGroupItems().size() - 1) {
                sb.append(SafeHtmlUtils.fromTrustedString(" "));
            }
        }
        if (!(top && !distributionFilterGroup.getInverted())) {
            sb.append(texts.groupEnd());
        }
    }

    private static void renderGroupItem(GroupItem groupItem, SafeHtmlBuilder sb) {
        if (groupItem instanceof DistributionFilterGroup) {
            renderDistributionFilterGroup(((DistributionFilterGroup) groupItem), sb, false);
        } else if (groupItem instanceof HcpSeatDistributionFilter) {
            renderHcpSeatDistributionFilter(((HcpSeatDistributionFilter) groupItem), sb);
        } else if (groupItem instanceof HcpSuitDistributionFilter) {
            renderHcpSuitDistributionFilter(((HcpSuitDistributionFilter) groupItem), sb);
        } else if (groupItem instanceof ShapeDistributionFilter) {
            renderShapeDistributionFilter(((ShapeDistributionFilter) groupItem), sb);
        } else if (groupItem instanceof ShapeTypeDistributionFilter) {
            renderShapeTypeDistributionFilter(((ShapeTypeDistributionFilter) groupItem), sb);
        } else if (groupItem instanceof FitDistributionFilter) {
            renderFitDistributionFilter(((FitDistributionFilter) groupItem), sb);
        } else if (groupItem instanceof MajorMinorDistributionFilter) {
            renderMajorMinorDistributionFilter(((MajorMinorDistributionFilter) groupItem), sb);
        } else if (groupItem instanceof NTDistributionFilter) {
            renderNTDistributionFilter(((NTDistributionFilter) groupItem), sb);
        } else if (groupItem instanceof LogicOperatorGroupItem) {
            renderLogicOperatorGroupItem(((LogicOperatorGroupItem) groupItem), sb);
        } else {
            throw new RuntimeException("Unknown type of groupitem: " + groupItem);
        }
    }

    private static void renderLogicOperatorGroupItem(LogicOperatorGroupItem logicOperatorGroupItem, SafeHtmlBuilder sb) {
        sb.append(RenderUtil.renderLogicOperator(logicOperatorGroupItem.getLogicOperator()));
    }

    private static void renderNTDistributionFilter(NTDistributionFilter ntDistributionFilter, SafeHtmlBuilder sb) {
        invertedStart(ntDistributionFilter, sb);
        SafeHtml M5m6indicator = null;
        if (ntDistributionFilter.getFiveCardMajorsAllowed() && ntDistributionFilter.getSixCardMinorsAllowed()) {
            M5m6indicator = SafeHtmlUtils.fromTrustedString("5M|6m");
        } else if (ntDistributionFilter.getFiveCardMajorsAllowed()) {
            M5m6indicator = SafeHtmlUtils.fromTrustedString("5M");
        } else if (ntDistributionFilter.getSixCardMinorsAllowed()) {
            M5m6indicator = SafeHtmlUtils.fromTrustedString("6m");
        } else {
            M5m6indicator = SafeHtmlUtils.fromTrustedString("");
        }
        sb.append(texts.nt(
                RenderUtil.renderSeatShort(ntDistributionFilter.getSeat()),
                RenderUtil.renderHcpInterval(ntDistributionFilter.getHcpInterval()),
                M5m6indicator));
        invertedEnd(ntDistributionFilter,sb);
    }

    private static void renderMajorMinorDistributionFilter(MajorMinorDistributionFilter majorMinorDistributionFilter, SafeHtmlBuilder sb) {
        invertedStart(majorMinorDistributionFilter, sb);
        sb.append(texts.majorMinor(
                RenderUtil.renderSeatShort(majorMinorDistributionFilter.getSeat()),
                RenderUtil.renderCardsCountInterval(majorMinorDistributionFilter.getMajorCardsCountInterval(),":"),
                RenderUtil.renderCardsCountInterval(majorMinorDistributionFilter.getMinorCardsCountInterval(),":")));
        invertedEnd(majorMinorDistributionFilter, sb);
    }

    private static void renderFitDistributionFilter(FitDistributionFilter fitDistributionFilter, SafeHtmlBuilder sb) {
        invertedStart(fitDistributionFilter, sb);
        sb.append(texts.fit(
                RenderUtil.renderSeatsShort(fitDistributionFilter.getSeats(),":"),
                RenderUtil.renderSuits(fitDistributionFilter.getSuits(),":"),
                RenderUtil.renderComparaOperator(fitDistributionFilter.getComparator()),
                fitDistributionFilter.getTotalCards()));
        invertedEnd(fitDistributionFilter, sb);
    }

    private static void renderShapeTypeDistributionFilter(ShapeTypeDistributionFilter shapeTypeDistributionFilter, SafeHtmlBuilder sb) {
        invertedStart(shapeTypeDistributionFilter, sb);
        sb.append(texts.shapeType(
                RenderUtil.renderSeatShort(shapeTypeDistributionFilter.getSeat()),
                RenderUtil.renderShapeType(shapeTypeDistributionFilter.getShapeType())));
        invertedEnd(shapeTypeDistributionFilter,sb);
    }

    private static void renderShapeDistributionFilter(ShapeDistributionFilter shapeDistributionFilter, SafeHtmlBuilder sb) {
        invertedStart(shapeDistributionFilter, sb);
        sb.append(texts.shape(
                RenderUtil.renderSeatShort(shapeDistributionFilter.getSeat()),
                RenderUtil.renderShape(shapeDistributionFilter.getShape())));
        invertedEnd(shapeDistributionFilter,sb);
    }

    private static void renderHcpSuitDistributionFilter(HcpSuitDistributionFilter hcpSuitDistributionFilter, SafeHtmlBuilder sb) {
        invertedStart(hcpSuitDistributionFilter, sb);
        sb.append(texts.hcpSuit(
                RenderUtil.renderSuits(hcpSuitDistributionFilter.getSuits(), ""),
                RenderUtil.renderHcpInterval(hcpSuitDistributionFilter.getHcpInterval()),
                RenderUtil.renderSeatShort(hcpSuitDistributionFilter.getSeat())));
        invertedEnd(hcpSuitDistributionFilter, sb);
    }

    private static void renderHcpSeatDistributionFilter(HcpSeatDistributionFilter hcpSeatDistributionFilter, SafeHtmlBuilder sb) {
        invertedStart(hcpSeatDistributionFilter, sb);
        sb.append(texts.hcpSeat(
                RenderUtil.renderSeatsShort(hcpSeatDistributionFilter.getSeats(), ""),
                RenderUtil.renderHcpInterval(hcpSeatDistributionFilter.getHcpInterval())));
        invertedEnd(hcpSeatDistributionFilter, sb);
    }

    private static void invertedEnd(DistributionFilterGroupItem item, SafeHtmlBuilder sb) {
        if (item.getInverted()) {
            sb.append(SafeHtmlUtils.fromTrustedString("}"));
        }
    }

    private static void invertedStart(DistributionFilterGroupItem item, SafeHtmlBuilder sb) {
        if (item.getInverted()) {
            sb.append(texts.inverted());
            sb.append(SafeHtmlUtils.fromTrustedString("{"));
        }
    }


    private DistributionFilterGroupRender() {
    }
}
